package com.mzpai.board.service.impl;

import java.util.Date;
import java.util.HashMap;
import java.util.List;
import java.util.Map;

import org.slf4j.Logger;
import org.slf4j.LoggerFactory;
import org.springframework.beans.factory.annotation.Autowired;
import org.springframework.stereotype.Service;

import com.mzpai.board.enums.CashKindEnum;
import com.mzpai.board.mapper.OperateCashLogMapper;
import com.mzpai.board.model.OperateCashLog;
import com.mzpai.board.model.StoreOrder;
import com.mzpai.board.service.OperateCashLogService;
import com.mzpai.board.service.StoreOrderService;
import com.mzpai.board.vo.OperateCashLogReqVo;
import com.mzpai.service.impl.BaseServiceImpl;
import com.mzpai.util.DateUtil;
import com.mzpai.util.StringUtils;

@Service
public class OperateCashLogServiceImpl extends BaseServiceImpl<OperateCashLog> implements OperateCashLogService {

	
	@Autowired
	private OperateCashLogMapper  operateCashLogMapper;
	@Autowired
	private StoreOrderService  storeOrderService;
	
	protected Logger logger = LoggerFactory.getLogger(OperateCashLogServiceImpl.class);
	@Override
	public void saveCashInfo(String nowTime) {
		long endDate = DateUtil.getHHNow();
		if(StringUtils.isNoneBlank(nowTime)) {
			endDate = DateUtil.getUTCTime(nowTime);
		}
		logger.info("msg1=保存现金参数时间={}", DateUtil.formatTime(endDate*1000));
		/**初始化记录*/
		List<StoreOrder> list = saveFlowLogInit(endDate);

		/**保存现金收入*/
		Map<String, StoreOrder> totalMap = addTotalMap(list);
		saveDayInfo(totalMap, endDate);
	}
	private void saveDayInfo(Map<String, StoreOrder> totalMap, long endDate) {
		List<StoreOrder> list = getListByHour(endDate);
		if(!list.isEmpty()) {
			String toDate = DateUtil.stringDateShortFormat(endDate*1000);
			Map<String, OperateCashLog> mapV = getOperateLogGroup(list, toDate);
			for(String key : mapV.keySet()){
				/**添加流量数据**/
				operateCashLogMapper.updateCashLog(mapV.get(key));
            }
		}
	}
	private Map<String, OperateCashLog> getOperateLogGroup(List<StoreOrder> list, String toDate) {
		Map<String, OperateCashLog> map = new HashMap<String, OperateCashLog>();
		for(StoreOrder s : list) {
			for(CashKindEnum ck : CashKindEnum.values()) {
				if(map.containsKey(toDate +";" + ck.getCode() + ";" + s.getStoreId())) {
					OperateCashLog vo = map.get(toDate +";" + s.getKindCode() + ";" + s.getStoreId());
					addCashLogHour(vo, s, ck.getCode(), false);
					map.put(toDate +";" + ck.getCode() + ";" + s.getStoreId(), vo);
				} else {
					OperateCashLog vo = new OperateCashLog();
					addCashLogHour(vo, s, ck.getCode(), true);
					map.put(toDate +";" + ck.getCode() + ";" + s.getStoreId(), vo);
				}
			}
		}
		return map;
	}
	
	
	/***
	 * 根据 kindcode, stroreid, createtime 
	 * @param vo
	 * @param s
	 */
	private void addCashLogHour(OperateCashLog vo, StoreOrder s, String kindCode, boolean b) {
		if(b) {
			vo.setKindCode(kindCode);
			String createTimeStr=s.getCreateTime();
			Date createTime=DateUtil.formatDateTime(createTimeStr,DateUtil.DATE);
			vo.setCreateTime(createTime);
			vo.setStoreId(s.getStoreId());
		}
		CashKindEnum cashKind = CashKindEnum.getType(kindCode);
		switch (cashKind) {
			case CASH_KIND_1 :
				addCashHour1Value(vo, s);
				break;
			case CASH_KIND_2:
				addCashHour2Value(vo, s);
				break;
			case CASH_KIND_3:
				addCashHour3Value(vo, s);
				break;
			case CASH_KIND_4:
				addCashHour4Value(vo, s);
				break;
			case CASH_KIND_5:
				addCashHour5Value(vo, s);
				break;
			case CASH_KIND_6:
				addCashHour6Value(vo, s);
				break;
			default:
				break;
			}
	}
	
	private void addCashHour1Value(OperateCashLog vo, StoreOrder s) {
		String sTime = s.getCreateTime().substring(11,13);
		switch (sTime) {
		case "00":
			vo.setH1(s.getTotalPrice());
			break;
		case "01":
			vo.setH2(s.getTotalPrice());
			break;
		case "02":
			vo.setH3(s.getTotalPrice());
			break;
		case "03":
			vo.setH4(s.getTotalPrice());
			break;
		case "04":
			vo.setH5(s.getTotalPrice());
			break;
		case "05":
			vo.setH6(s.getTotalPrice());
			break;
		case "06":
			vo.setH7(s.getTotalPrice());
			break;
		case "07":
			vo.setH8(s.getTotalPrice());
			break;
		case "08":
			vo.setH9(s.getTotalPrice());
			break;
		case "09":
			vo.setH10(s.getTotalPrice());
			break;
		case "10":
			vo.setH11(s.getTotalPrice());
			break;
		case "11":
			vo.setH12(s.getTotalPrice());
			break;
		case "12":
			vo.setH13(s.getTotalPrice());
			break;
		case "13":
			vo.setH14(s.getTotalPrice());
			break;
		case "14":
			vo.setH15(s.getTotalPrice());
			break;
		case "15":
			vo.setH16(s.getTotalPrice());
			break;
		case "16":
			vo.setH17(s.getTotalPrice());
			break;
		case "17":
			vo.setH18(s.getTotalPrice());
			break;
		case "18":
			vo.setH19(s.getTotalPrice());
			break;
		case "19":
			vo.setH20(s.getTotalPrice());
			break;
		case "20":
			vo.setH21(s.getTotalPrice());
			break;
		case "21":
			vo.setH22(s.getTotalPrice());
			break;
		case "22":
			vo.setH23(s.getTotalPrice());
			break;
		case "23":
			vo.setH24(s.getTotalPrice());
			break;
		default:
			break;
		}
	}
	
	
	private void addCashHour2Value(OperateCashLog vo, StoreOrder s) {
		String sTime = s.getCreateTime().substring(11,13);
		switch (sTime) {
		case "00":
			vo.setH1(s.getPayPrice());
			break;
		case "01":
			vo.setH2(s.getPayPrice());
			break;
		case "02":
			vo.setH3(s.getPayPrice());
			break;
		case "03":
			vo.setH4(s.getPayPrice());
			break;
		case "04":
			vo.setH5(s.getPayPrice());
			break;
		case "05":
			vo.setH6(s.getPayPrice());
			break;
		case "06":
			vo.setH7(s.getPayPrice());
			break;
		case "07":
			vo.setH8(s.getPayPrice());
			break;
		case "08":
			vo.setH9(s.getPayPrice());
			break;
		case "09":
			vo.setH10(s.getPayPrice());
			break;
		case "10":
			vo.setH11(s.getPayPrice());
			break;
		case "11":
			vo.setH12(s.getPayPrice());
			break;
		case "12":
			vo.setH13(s.getPayPrice());
			break;
		case "13":
			vo.setH14(s.getPayPrice());
			break;
		case "14":
			vo.setH15(s.getPayPrice());
			break;
		case "15":
			vo.setH16(s.getPayPrice());
			break;
		case "16":
			vo.setH17(s.getPayPrice());
			break;
		case "17":
			vo.setH18(s.getPayPrice());
			break;
		case "18":
			vo.setH19(s.getPayPrice());
			break;
		case "19":
			vo.setH20(s.getPayPrice());
			break;
		case "20":
			vo.setH21(s.getPayPrice());
			break;
		case "21":
			vo.setH22(s.getPayPrice());
			break;
		case "22":
			vo.setH23(s.getPayPrice());
			break;
		case "23":
			vo.setH24(s.getPayPrice());
			break;
		default:
			break;
		}
	}
	
	
	private void addCashHour3Value(OperateCashLog vo, StoreOrder s) {
		String sTime = s.getCreateTime().substring(11,13);
		switch (sTime) {
		case "00":
			vo.setH1(s.getPayCount());
			break;
		case "01":
			vo.setH2(s.getPayCount());
			break;
		case "02":
			vo.setH3(s.getPayCount());
			break;
		case "03":
			vo.setH4(s.getPayCount());
			break;
		case "04":
			vo.setH5(s.getPayCount());
			break;
		case "05":
			vo.setH6(s.getPayCount());
			break;
		case "06":
			vo.setH7(s.getPayCount());
			break;
		case "07":
			vo.setH8(s.getPayCount());
			break;
		case "08":
			vo.setH9(s.getPayCount());
			break;
		case "09":
			vo.setH10(s.getPayCount());
			break;
		case "10":
			vo.setH11(s.getPayCount());
			break;
		case "11":
			vo.setH12(s.getPayCount());
			break;
		case "12":
			vo.setH13(s.getPayCount());
			break;
		case "13":
			vo.setH14(s.getPayCount());
			break;
		case "14":
			vo.setH15(s.getPayCount());
			break;
		case "15":
			vo.setH16(s.getPayCount());
			break;
		case "16":
			vo.setH17(s.getPayCount());
			break;
		case "17":
			vo.setH18(s.getPayCount());
			break;
		case "18":
			vo.setH19(s.getPayCount());
			break;
		case "19":
			vo.setH20(s.getPayCount());
			break;
		case "20":
			vo.setH21(s.getPayCount());
			break;
		case "21":
			vo.setH22(s.getPayCount());
			break;
		case "22":
			vo.setH23(s.getPayCount());
			break;
		case "23":
			vo.setH24(s.getPayCount());
			break;
		default:
			break;
		}
	} 
	
	
	private void addCashHour4Value(OperateCashLog vo, StoreOrder s) {
		String sTime = s.getCreateTime().substring(11,13);
		switch (sTime) {
		case "00":
			vo.setH1(s.getTotalCount());
			break;
		case "01":
			vo.setH2(s.getTotalCount());
			break;
		case "02":
			vo.setH3(s.getTotalCount());
			break;
		case "03":
			vo.setH4(s.getTotalCount());
			break;
		case "04":
			vo.setH5(s.getTotalCount());
			break;
		case "05":
			vo.setH6(s.getTotalCount());
			break;
		case "06":
			vo.setH7(s.getTotalCount());
			break;
		case "07":
			vo.setH8(s.getTotalCount());
			break;
		case "08":
			vo.setH9(s.getTotalCount());
			break;
		case "09":
			vo.setH10(s.getTotalCount());
			break;
		case "10":
			vo.setH11(s.getTotalCount());
			break;
		case "11":
			vo.setH12(s.getTotalCount());
			break;
		case "12":
			vo.setH13(s.getTotalCount());
			break;
		case "13":
			vo.setH14(s.getTotalCount());
			break;
		case "14":
			vo.setH15(s.getTotalCount());
			break;
		case "15":
			vo.setH16(s.getTotalCount());
			break;
		case "16":
			vo.setH17(s.getTotalCount());
			break;
		case "17":
			vo.setH18(s.getTotalCount());
			break;
		case "18":
			vo.setH19(s.getTotalCount());
			break;
		case "19":
			vo.setH20(s.getTotalCount());
			break;
		case "20":
			vo.setH21(s.getTotalCount());
			break;
		case "21":
			vo.setH22(s.getTotalCount());
			break;
		case "22":
			vo.setH23(s.getTotalCount());
			break;
		case "23":
			vo.setH24(s.getTotalCount());
			break;
		default:
			break;
		}
	} 
	
	
	private void addCashHour5Value(OperateCashLog vo, StoreOrder s) {
		String sTime = s.getCreateTime().substring(11,13);
		switch (sTime) {
		case "00":
			vo.setH1(s.getNoPayCount());
			break;
		case "01":
			vo.setH2(s.getNoPayCount());
			break;
		case "02":
			vo.setH3(s.getNoPayCount());
			break;
		case "03":
			vo.setH4(s.getNoPayCount());
			break;
		case "04":
			vo.setH5(s.getNoPayCount());
			break;
		case "05":
			vo.setH6(s.getNoPayCount());
			break;
		case "06":
			vo.setH7(s.getNoPayCount());
			break;
		case "07":
			vo.setH8(s.getNoPayCount());
			break;
		case "08":
			vo.setH9(s.getNoPayCount());
			break;
		case "09":
			vo.setH10(s.getNoPayCount());
			break;
		case "10":
			vo.setH11(s.getNoPayCount());
			break;
		case "11":
			vo.setH12(s.getNoPayCount());
			break;
		case "12":
			vo.setH13(s.getNoPayCount());
			break;
		case "13":
			vo.setH14(s.getNoPayCount());
			break;
		case "14":
			vo.setH15(s.getNoPayCount());
			break;
		case "15":
			vo.setH16(s.getNoPayCount());
			break;
		case "16":
			vo.setH17(s.getNoPayCount());
			break;
		case "17":
			vo.setH18(s.getNoPayCount());
			break;
		case "18":
			vo.setH19(s.getNoPayCount());
			break;
		case "19":
			vo.setH20(s.getNoPayCount());
			break;
		case "20":
			vo.setH21(s.getNoPayCount());
			break;
		case "21":
			vo.setH22(s.getNoPayCount());
			break;
		case "22":
			vo.setH23(s.getNoPayCount());
			break;
		case "23":
			vo.setH24(s.getNoPayCount());
			break;
		default:
			break;
		}
	} 
	
	
	private void addCashHour6Value(OperateCashLog vo, StoreOrder s) {
		String sTime = s.getCreateTime().substring(11,13);
		switch (sTime) {
		case "00":
			vo.setH1(s.getCannelCount());
			break;
		case "01":
			vo.setH2(s.getCannelCount());
			break;
		case "02":
			vo.setH3(s.getCannelCount());
			break;
		case "03":
			vo.setH4(s.getCannelCount());
			break;
		case "04":
			vo.setH5(s.getCannelCount());
			break;
		case "05":
			vo.setH6(s.getCannelCount());
			break;
		case "06":
			vo.setH7(s.getCannelCount());
			break;
		case "07":
			vo.setH8(s.getCannelCount());
			break;
		case "08":
			vo.setH9(s.getCannelCount());
			break;
		case "09":
			vo.setH10(s.getCannelCount());
			break;
		case "10":
			vo.setH11(s.getCannelCount());
			break;
		case "11":
			vo.setH12(s.getCannelCount());
			break;
		case "12":
			vo.setH13(s.getCannelCount());
			break;
		case "13":
			vo.setH14(s.getCannelCount());
			break;
		case "14":
			vo.setH15(s.getCannelCount());
			break;
		case "15":
			vo.setH16(s.getCannelCount());
			break;
		case "16":
			vo.setH17(s.getCannelCount());
			break;
		case "17":
			vo.setH18(s.getCannelCount());
			break;
		case "18":
			vo.setH19(s.getCannelCount());
			break;
		case "19":
			vo.setH20(s.getCannelCount());
			break;
		case "20":
			vo.setH21(s.getCannelCount());
			break;
		case "21":
			vo.setH22(s.getCannelCount());
			break;
		case "22":
			vo.setH23(s.getCannelCount());
			break;
		case "23":
			vo.setH24(s.getCannelCount());
			break;
		default:
			break;
		}
	} 
	
	
	/**
	 * 分组
	 * @param list
	 * @return
	 */
	private Map<String, StoreOrder> addTotalMap(List<StoreOrder> list) {
		Map<String, StoreOrder> totalMap = new HashMap<String,StoreOrder>();
		for(StoreOrder o : list) {
			for(CashKindEnum s : CashKindEnum.values()) {
				totalMap.put(o.getCreateDate() + ";" + s.getCode() + ";" + o.getStoreId(), o);
			}
		}
		return totalMap;
	}

	/**
	 * 查询近一个小时的数据结果
	 * @param nowTime
	 * @return
	 */
	private List<StoreOrder> getListByHour(long nowTime) {
		Map<String, Object> map = new HashMap<String, Object>();
		map.put("beginDate", nowTime - 3600);
		map.put("endDate", nowTime);
		return storeOrderService.getListByHour(map);
	}

	/***
	 * 初始化数据
	 * 如果没有，需要insert 如果存在，不做操作
	 * 4个小时
	 * @param list
	 * @param map
	 */
	private List<StoreOrder> saveFlowLogInit(long nowTime) {
		Map<String, Object> map = new HashMap<String, Object>();
		map.put("beginDate", nowTime - 3600);
		map.put("endDate", nowTime);
		List<StoreOrder> list = storeOrderService.getListByDate(map);
		/****
		if(list.isEmpty()) {
			//list == empty 需要判断当前是初始化过
			map.put("createDate", DateUtil.stringDateShortFormat(nowTime));
			if(storeOrderService.getCount(map) == 0 ) {
				StoreOrder o = new StoreOrder();
				o.setCreateDate(DateUtil.stringDateShortFormat(nowTime));
				list.clear();
				list.add(o);
			}
		}
		***/
		
		List<OperateCashLog> smptList = null;
		for(StoreOrder o : list) {
			/**上周数据*/
			map.clear();
			map.put("storeId", o.getStoreId());
			map.put("createDate", DateUtil.getBeforeAfterDateString(o.getCreateDate(), -7));
			StoreOrder lastWeekOrder = getStoreOrderObject(map);
			
			/**上周数据*/
			map.put("createDate", DateUtil.getBeforeAfterDateString(o.getCreateDate(), -1));
			StoreOrder lastDayOrder = getStoreOrderObject(map);
			
			/***定义现金流收入类型**/
			for(CashKindEnum s : CashKindEnum.values()) {
				map.clear();
				map.put("createTime", o.getCreateDate());
				map.put("kindCode", s.getCode());
				map.put("storeId", o.getStoreId());
				smptList = operateCashLogMapper.getList(map);
				if(smptList.isEmpty() || smptList.size() == 0) {
					insertCashLog(s.getCode(), o, lastWeekOrder, lastDayOrder);
				}
			}
		}
		return list;
	}


	private StoreOrder getStoreOrderObject(Map<String, Object> map) {
		List<StoreOrder> o = storeOrderService.getListByDate(map);
		if(o.isEmpty() || o.size() == 0) {
			return new StoreOrder();
		}
		return o.get(0);
	}

	/**
	 * 保存现金收入
	 * @param kindCode
	 * @param o
	 */
	private void insertCashLog(String kindCode, StoreOrder o, StoreOrder lastWeekInfo, StoreOrder lastDayInfo) {
		OperateCashLog log = new OperateCashLog();
		log.setKindCode(kindCode);
		
		String createDateStr=o.getCreateDate();
		Date createTime=DateUtil.formatDateTime(createDateStr,DateUtil.DATE);
		log.setCreateTime(createTime);
		log.setStoreId(o.getStoreId());
		log.setStoreName(o.getStoreName());
		/**保存金额*/
		CashKindEnum cashKind = CashKindEnum.getType(kindCode);
		switch (cashKind) {
			case CASH_KIND_1 :
				log.setTotal(o.getTotalPrice());
				log.setLastWeekTotal(lastWeekInfo.getTotalPrice());
				log.setLastDayTotal(lastDayInfo.getTotalPrice());
				break;
			case CASH_KIND_2:
				log.setTotal(o.getPayPrice());
				log.setLastWeekTotal(lastWeekInfo.getPayPrice());
				log.setLastDayTotal(lastDayInfo.getPayPrice());
				break;
			case CASH_KIND_3:
				log.setTotal(o.getPayCount());
				log.setLastWeekTotal(lastWeekInfo.getPayCount());
				log.setLastDayTotal(lastDayInfo.getPayCount());
				break;
			case CASH_KIND_4:
				log.setTotal(o.getTotalCount());
				log.setLastWeekTotal(lastWeekInfo.getTotalCount());
				log.setLastDayTotal(lastDayInfo.getTotalCount());
				break;
			case CASH_KIND_5:
				log.setTotal(o.getNoPayCount());
				log.setLastWeekTotal(lastWeekInfo.getNoPayCount());
				log.setLastDayTotal(lastDayInfo.getNoPayCount());
				break;
			case CASH_KIND_6:
				log.setTotal(o.getCannelCount());
				log.setLastWeekTotal(lastWeekInfo.getCannelCount());
				log.setLastDayTotal(lastDayInfo.getCannelCount());
				break;
			default:
				break;
			}
		operateCashLogMapper.insert(log);
	}

	
	@Override
	public List<OperateCashLog> getCashLogListGroupByKindCodeCreateTime(OperateCashLogReqVo operateCashLogReqVo) {
		String startDateStr=operateCashLogReqVo.getStartDate();
		String endDateStr=operateCashLogReqVo.getEndDate();
		String storeId=operateCashLogReqVo.getStoreId();
		String kindCode=operateCashLogReqVo.getKindCode();
		//结束时间为空 则默认和开始时间一样只查当天
        if(StringUtils.isNullOrBlank(endDateStr)){
        	endDateStr=startDateStr;
		}
        
        String startStr=DateUtil.formatDateStr(startDateStr,DateUtil.DATE); 
        String endStr=DateUtil.formatDateStr(endDateStr,DateUtil.DATE); 
		
		Map<String,Object> operateCashLogMap=new HashMap<String,Object>();
		operateCashLogMap.put("startDate", startStr);
		operateCashLogMap.put("endDate", endStr);
		operateCashLogMap.put("kindCode", kindCode);
		operateCashLogMap.put("storeId", storeId);
		List<OperateCashLog> operateCashLogList=operateCashLogMapper.getCashLogListGroupByKindCodeCreateTime(operateCashLogMap);
		
		return operateCashLogList;
	}
	@Override
	public List<OperateCashLog> getCashLogListGroupByStoreIdKindCodeCreateTime(OperateCashLogReqVo operateCashLogReqVo) {
		String startDateStr=operateCashLogReqVo.getStartDate();
		String endDateStr=operateCashLogReqVo.getEndDate();
		String storeId=operateCashLogReqVo.getStoreId();
		String kindCode=operateCashLogReqVo.getKindCode();
		//结束时间为空 则默认和开始时间一样只查当天
        if(StringUtils.isNullOrBlank(endDateStr)){
        	endDateStr=startDateStr;
		}
        
        String startStr=DateUtil.formatDateStr(startDateStr,DateUtil.DATE); 
        String endStr=DateUtil.formatDateStr(endDateStr,DateUtil.DATE); 
		
		Map<String,Object> operateCashLogMap=new HashMap<String,Object>();
		operateCashLogMap.put("startDate", startStr);
		operateCashLogMap.put("endDate", endStr);
		operateCashLogMap.put("kindCode", kindCode);
		operateCashLogMap.put("storeId", storeId);
		List<OperateCashLog> operateCashLogList=operateCashLogMapper.getCashLogListGroupByStoreIdKindCodeCreateTime(operateCashLogMap);
		
		return operateCashLogList;
	}

}
